package com.study.shengsiyuan.example08;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.Iterator;

import com.study.shengsiyuan.example08.proto.MyRequest;
import com.study.shengsiyuan.example08.proto.MyResponse;
import com.study.shengsiyuan.example08.proto.StreamRequest;
import com.study.shengsiyuan.example08.proto.StreamResponse;
import com.study.shengsiyuan.example08.proto.StudentRequest;
import com.study.shengsiyuan.example08.proto.StudentResponse;
import com.study.shengsiyuan.example08.proto.StudentResponseList;
import com.study.shengsiyuan.example08.proto.StudentServiceGrpc;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import io.grpc.stub.StreamObserver;

public class GrpcClient {


	public static void main(String[] args) throws IOException, InterruptedException {
		ManagedChannel managedChannel = ManagedChannelBuilder
				.forAddress("localhost", 8899)
				.usePlaintext().build();
		//同步的（阻塞的）
		StudentServiceGrpc.StudentServiceBlockingStub blockingStub =  StudentServiceGrpc.newBlockingStub(managedChannel);
		//异步的（非阻塞的）
		StudentServiceGrpc.StudentServiceStub stub =  StudentServiceGrpc.newStub(managedChannel);

		System.out.println("-------------- getRealnameByUsername --------------------");
		// blockingStub.getRealnameByUsername（）  是一个阻塞方法 ：发送请求后，等待服务端的响应
		MyResponse myResponse = blockingStub.getRealnameByUsername(
					MyRequest.newBuilder().setUsername("zhangshan").build());
		System.out.println(myResponse.getRealname());
		//socket 连接是长连接，连接后不会断的
		//就是只有第一次连接会有短暂的等待时间（就是建立连接花费的时间）
		//以后的请求都没有这个等待时间。
		//通过以下循环可以看出：只有开始出现短暂的延迟，而所有结果都是一次显示出来的。

//		for (int i = 0; i < 10; i++) {
//			myResponse = blockingStub.getRealnameByUsername(
//					MyRequest.newBuilder().setUsername("zhangshan").build());
//			System.out.println(myResponse.getRealname());
//		}

		System.out.println("-------------- getStudentsByAge --------------------");
		// blockingStub.getStudentsByAge（）  是一个阻塞方法 ：发送请求后，等待服务端的响应
		Iterator<StudentResponse> it=blockingStub.getStudentsByAge(StudentRequest.newBuilder().setAge(12).build());

		while(it.hasNext()) {
			StudentResponse sr = it.next();
			System.out.println("姓名 ："+sr.getName()+" , 年龄 ："+sr.getAge()+" , 住址 ："+sr.getCity());
		}

		System.out.println("--------------- getStudentsWrapperByAges -------------------");

		//第一步，客户端接收到的服务端的响应
		StreamObserver<StudentResponseList> ro = new StreamObserver<StudentResponseList>() {

			@Override
			public void onNext(StudentResponseList value) {
				value.getStudentResponseList().forEach(sr->{
					System.out.println("姓名 ："+sr.getName()+" , 年龄 ："+sr.getAge()+" , 住址 ："+sr.getCity());
					System.out.println("**********************************************");
				});

			}

			@Override
			public void onError(Throwable t) { }

			@Override
			public void onCompleted() { }

		};
		//第二步 客户端发送请求
		// stub.getStudentsWrapperByAges（）  是一个非阻塞方法 ：发送请求后，不会等待，直接向下执行代码。
		StreamObserver<StudentRequest> ros = stub.getStudentsWrapperByAges(ro);
		ros.onNext(StudentRequest.newBuilder().setAge(22).build());
		ros.onNext(StudentRequest.newBuilder().setAge(32).build());
		ros.onNext(StudentRequest.newBuilder().setAge(52).build());
		ros.onCompleted();
		Thread.sleep(5000);//客户端请求等待服务器响应完成。


		System.out.println("--------------- biTalk -------------------");

		//第一步，客户端接收到的服务端的响应
				StreamObserver<StreamResponse> ro2 = new StreamObserver<StreamResponse>() {

					@Override
					public void onNext(StreamResponse value) {
						System.out.println(value.getResponseInfo());
					}

					@Override
					public void onError(Throwable t) { }

					@Override
					public void onCompleted() { }

				};
				//第二步 客户端发送请求
				// stub.getStudentsWrapperByAges（）  是一个非阻塞方法 ：发送请求后，不会等待，直接向下执行代码。
				StreamObserver<StreamRequest> ros2 = stub.biTalk(ro2);
				for (int i = 0; i <10; i++) {
					ros2.onNext(StreamRequest.newBuilder().setRequestInfo(LocalDateTime.now().toString()).build());
					Thread.sleep(1000);
				}
				ros.onCompleted();
				Thread.sleep(5000);//客户端请求等待服务器响应完成。

	}
}
